package com.xbongbong.saas.enums;

import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import lombok.Getter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 入库类型枚举
 *
 * @author GuoJun.HU
 * @since 3.26
 * 创建时间 2018/8/8 10:50
 */
@Getter
public enum InstockTypeEnum {

    /**
     * 采购入库
     */
    PURCHASE_INSTOCK(1, "enum.instockType.name.purchase_instock", "purchase", XbbRefTypeEnum.PURCHASE.getCode(), XbbRefTypeEnum.PURCHASE_INSTOCK.getCode(), OperateModuleTypeEnum.PURCHASE_INSTOCK),
    /**
     * 合同订单退货入库
     */
    RED_CONTRACT_INSTOCK(2, "enum.instockType.name.red_contract_instock", "redContract", XbbRefTypeEnum.REFUND.getCode(), XbbRefTypeEnum.REFUND_INSTOCK.getCode(), OperateModuleTypeEnum.REFUND_INSTOCK),
    /**
     * 盘盈入库
     */
    INVENTORY_INSTOCK(3, "enum.instockType.name.inventory_instock", "inventory", XbbRefTypeEnum.INVENTORY.getCode(), XbbRefTypeEnum.OTHER_INSTOCK.getCode(), OperateModuleTypeEnum.INSTOCK),
    /**
     * 调拨入库
     */
    TRANSFER_INSTOCK(4, "enum.instockType.name.transfer_instock", "transfer", XbbRefTypeEnum.TRANSFER.getCode(), XbbRefTypeEnum.OTHER_INSTOCK.getCode(),  OperateModuleTypeEnum.INSTOCK),
    /**
     * 其他入库
     */
    OTHER_INSTOCK(5, "enum.instockType.name.other_instock", "other", XbbRefTypeEnum.OTHER_INSTOCK.getCode(), XbbRefTypeEnum.OTHER_INSTOCK.getCode(), OperateModuleTypeEnum.INSTOCK),
    /**
     * 装配入库
     */
    ASSEMBLE_INSTOCK(6, "enum.instockType.name.assemble_instock", "assemble", XbbRefTypeEnum.ASSEMBLE.getCode(), XbbRefTypeEnum.OTHER_INSTOCK.getCode(),  OperateModuleTypeEnum.INSTOCK),
    /**
     * 生产成品入库(对应生产单)
     */
    FINSHED_PRODUCT_INSTOCK(7, "enum.instockType.name.finshed_product_instock", "finshedProduct", XbbRefTypeEnum.PRODUCTION_ORDER.getCode(), XbbRefTypeEnum.PRODUCTION_INSTOCK.getCode(), OperateModuleTypeEnum.PRODUCTION_INSTOCK),
    /**
     * 生产退料入库
     */
    RETURNED_MATERIEL_INSTOCK(8, "enum.instockType.name.returned_materiel_instock", "returnedMateriel", XbbRefTypeEnum.PRODUCTION_ORDER.getCode(), XbbRefTypeEnum.RETURNED_MATERIEL_INSTOCK.getCode(), OperateModuleTypeEnum.RETURNED_MATERIEL_INSTOCK),
    /**
     * 未知类型
     */
    UNKNOWN(404, "enum.instockType.name.unknown", "unknown", XbbRefTypeEnum.UNKNOWN.getCode(), XbbRefTypeEnum.UNKNOWN.getCode(), OperateModuleTypeEnum.UNKNOWN);

    /**
     * 枚举值
     */
    private final int code;

    /**
     * 枚举中文描述
     */
    private final String name;

    /**
     * 枚举英文描述
     */
    private final String alias;

    /**
     * 业务类型
     */
    private final Integer businessType;

    /**
     * 单据类型
     */
    private final Integer stockBusinessType;

    /**
     * 日志类型
     */
    private final OperateModuleTypeEnum operateModuleTypeEnum;

    InstockTypeEnum(int code, String name, String alias, Integer businessType, Integer stockBusinessType, OperateModuleTypeEnum operateModuleTypeEnum) {
        this.code = code;
        this.name = name;
        this.alias = alias;
        this.businessType = businessType;
        this.stockBusinessType = stockBusinessType;
        this.operateModuleTypeEnum = operateModuleTypeEnum;
    }

    public static String getByBuisenssType(Integer linkBusinessType) {
        for (InstockTypeEnum cacheCode : values()) {
            if (cacheCode.getBusinessType().equals(linkBusinessType)) {
                return String.valueOf(cacheCode.getCode());
            }
        }
        return String.valueOf(OTHER_INSTOCK.getCode());
    }

    public static Boolean getByStockBuisenssType(Integer linkBusinessType) {
        for (InstockTypeEnum cacheCode : values()) {
            if (cacheCode.getStockBusinessType().equals(linkBusinessType)) {
                return true;
            }
        }
        return false;
    }

    public static InstockTypeEnum getByStockBusinessType(Integer stockBusinessType) {
        for (InstockTypeEnum cacheCode : values()) {
            if (Objects.equals(stockBusinessType, XbbRefTypeEnum.OTHER_INSTOCK.getCode())) {
                return OTHER_INSTOCK;
            } else {
                if (cacheCode.getStockBusinessType().equals(stockBusinessType)) {
                    return cacheCode;
                }
            }
        }
        return OTHER_INSTOCK;
    }

    public static List<Integer> getInstockTypeEnumsByStockBusinessType(Integer stockBusinessType) {
        List<InstockTypeEnum> instockTypeEnumList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (InstockTypeEnum cacheCode : values()) {
            if (Objects.equals(stockBusinessType, cacheCode.stockBusinessType)) {
                instockTypeEnumList.add(cacheCode);
            }
        }
        List<Integer> result = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        instockTypeEnumList.forEach(item -> result.add(item.code));
        return result;
    }

    public static Map<Integer,List<Integer>> getStockTypeMap() {
        Map<Integer,List<Integer>> map =  new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Integer> typeList;
        for (InstockTypeEnum instockTypeEnum : values()) {
            if (map.containsKey(instockTypeEnum.getStockBusinessType())) {
                typeList = map.get(instockTypeEnum.getStockBusinessType());
            } else {
                typeList = new ArrayList<>();
            }
            typeList.add(instockTypeEnum.getCode());
            map.put(instockTypeEnum.getStockBusinessType(), typeList);
        }
        return map;
    }

    public static Integer getByBuisenssTypeInt(Integer linkBusinessType) {
        for (InstockTypeEnum cacheCode : values()) {
            if (cacheCode.getBusinessType().equals(linkBusinessType)) {
                return cacheCode.getCode();
            }
        }
        return OTHER_INSTOCK.getCode();
    }

    /**
     * 通过枚举<code>alias</code>获得枚举
     *
     * @param alias 别名
     * @return InstockTypeEnum
     */
    public static InstockTypeEnum getByAlias(String alias) {
        for (InstockTypeEnum cacheCode : values()) {
            if (cacheCode.getAlias().equals(alias)) {
                return cacheCode;
            }
        }
        return UNKNOWN;
    }

    /**
     * 通过枚举<code>name</code>获得枚举
     *
     * @param name 名称
     * @return InstockTypeEnum
     */
    public static InstockTypeEnum getByName(String name) {
        for (InstockTypeEnum cacheCode : values()) {
            if (cacheCode.getName().equals(name)) {
                return cacheCode;
            }
        }
        return UNKNOWN;
    }

    /**
     * 通过枚举<code>code</code>获得枚举
     *
     * @param code 枚举值
     * @return InstockTypeEnum
     */
    public static InstockTypeEnum getByCode(Integer code) {
        for (InstockTypeEnum cacheCode : values()) {
            if (Objects.equals(code,cacheCode.getCode())) {
                return cacheCode;
            }
        }
        return UNKNOWN;
    }

    /**
     * 根据code获取类型名称
     * @param code
     * @return java.lang.String
     * @author zcp
     * @date 2019/4/8 16:58
     * @since v1.0
     * @version v1.0
     */
    public static String getTypeNameByCode(Integer code) {
        for (InstockTypeEnum cacheCode : values()) {
            if (Objects.equals(code,cacheCode.getCode())) {
                return cacheCode.getName();
            }
        }
        return "";
    }

    /**
     * 获取全部枚举
     */
    public static List<InstockTypeEnum> getAllEnum() {
        List<InstockTypeEnum> list = new ArrayList<>();
        for (InstockTypeEnum cache : values()) {
            if (cache == UNKNOWN) {
                continue;
            }
            list.add(cache);
        }
        return list;
    }

    /**
     * 获取全部枚举值
     */
    public static List<String> getAllEnumAlis() {
        List<String> list = new ArrayList<>();
        for (InstockTypeEnum cache : values()) {
            if (cache == UNKNOWN) {
                continue;
            }
            list.add(cache.getAlias());
        }
        return list;
    }
    /**
     * 通过name获取关联的businessType
     */
    public static Integer getBusinessByName(String name) {
        for (InstockTypeEnum cacheCode : values()) {
            if (name.equals(cacheCode.getName())) {
                return cacheCode.businessType;
            }
        }
        return 0;
    }

    /**
     * 通过code获取关联的businessType
     */
    public static Integer getBusinessByCode(Integer code) {
        for (InstockTypeEnum cacheCode : values()) {
            if (Objects.equals(code,cacheCode.getCode())) {
                return cacheCode.businessType;
            }
        }
        return 0;
    }


    public static Integer getStockBusinessTypeByCode(Integer code) {
        for (InstockTypeEnum cacheCode : values()) {
            if (Objects.equals(code,cacheCode.getCode())) {
                return cacheCode.stockBusinessType;
            }
        }
        return 0;
    }

    /**
     * 获取全部枚举的名称
     */
    public static List<String> getAllEnumNames() {
        List<String> list = new ArrayList<>();
        for (InstockTypeEnum cache : values()) {
            if (cache == UNKNOWN) {
                continue;
            }
            list.add(cache.getName());
        }
        return list;
    }

    /**
     * 获取全部枚举的名称作为导入模板中的入库类型字段的下拉选项
     */
    public static String[] getAllEnumNamesForImportOptions() {
        List<String> list = new ArrayList<>();
        for (InstockTypeEnum cache : values()) {
            if (cache == UNKNOWN || cache == ASSEMBLE_INSTOCK) {
                continue;
            }
            list.add(cache.getName());
        }
        return list.toArray(new String[list.size()]);
    }

    /**
     * 获取入库类型code和name的关系
     *
     * @author GuoJun.HU
     * @since 3.27
     * 创建时间 2018/9/10 10:00
     */
    public static Map<Integer, String> getInstockTypeMap() {
        Map<Integer, String> typeMap = new LinkedHashMap<>(16);
        for (InstockTypeEnum instockTypeEnum : getAllEnum()) {
            typeMap.put(instockTypeEnum.getCode(), instockTypeEnum.getName());
        }
        return typeMap;
    }

    public static Map<Integer,String> getOtherInstockTypeMap() {
        Map<Integer, String> typeMap = new LinkedHashMap<>(16);
        typeMap.put(INVENTORY_INSTOCK.getCode(),INVENTORY_INSTOCK.getName());
        typeMap.put(TRANSFER_INSTOCK.getCode(),TRANSFER_INSTOCK.getName());
        typeMap.put(OTHER_INSTOCK.getCode(),OTHER_INSTOCK.getName());
        typeMap.put(ASSEMBLE_INSTOCK.getCode(),ASSEMBLE_INSTOCK.getName());
        return typeMap;
    }

    public String getName() {
        return I18nMessageUtil.getMessage(name);
    }
}
